home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Resources / Online / Term / Extras / Source / term-source.lha / Traps.c < prev    next >
C/C++ Source or Header  |  1996-10-20  |  8KB  |  410 lines

  1. /*
  2. **    Traps.c
  3. **
  4. **    Trap routines
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9. **    :ts=4
  10. */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "Global.h"
  14. #endif
  15.  
  16. struct TrapNode *
  17. ChangeTrapNode(struct GenericList *TrapList,struct TrapNode *Current,STRPTR Sequence,STRPTR Command)
  18. {
  19.     struct TrapNode *New;
  20.  
  21.     if(!Sequence)
  22.         Sequence = Current->Node.ln_Name;
  23.  
  24.     if(!Command)
  25.         Command = Current->Command;
  26.  
  27.     if(New = CreateTrapNode(Sequence,Command))
  28.     {
  29.         Insert((struct List *)TrapList,(struct Node *)New,(struct Node *)Current);
  30.  
  31.         Remove((struct Node *)Current);
  32.  
  33.         FreeVecPooled(Current);
  34.  
  35.         return(New);
  36.     }
  37.     else
  38.         return(Current);
  39. }
  40.  
  41. struct TrapNode *
  42. CreateTrapNode(STRPTR SequenceBuffer,STRPTR CommandBuffer)
  43. {
  44.     UBYTE LocalBuffer[256];
  45.     struct TrapNode    *Node;
  46.     LONG Len;
  47.  
  48.     Len = TranslateString(SequenceBuffer,LocalBuffer);
  49.  
  50.     if(Node = (struct TrapNode *)AllocVecPooled(sizeof(struct TrapNode) + strlen(SequenceBuffer) + 1 + Len + strlen(CommandBuffer) + 1,MEMF_ANY))
  51.     {
  52.         STRPTR String;
  53.  
  54.         String = Node->Node.ln_Name = (STRPTR)(Node + 1);
  55.  
  56.         strcpy(String,SequenceBuffer);
  57.  
  58.         String += strlen(String) + 1;
  59.  
  60.         Node->Sequence = String;
  61.  
  62.         CopyMem(LocalBuffer,String,Len);
  63.  
  64.         String += Len;
  65.  
  66.         Node->Command = String;
  67.  
  68.         Node->SequenceLen = Len;
  69.         Node->Count = 0;
  70.  
  71.         strcpy(String,CommandBuffer);
  72.     }
  73.  
  74.     return(Node);
  75. }
  76.  
  77.     /* SaveTraps(STRPTR Name):
  78.      *
  79.      *    Save the trap list to a file.
  80.      */
  81.  
  82. BOOL
  83. SaveTraps(STRPTR Name,struct List *TrapList)
  84. {
  85.     struct IFFHandle *Handle;
  86.     LONG Error;
  87.  
  88.     if(!(Handle = OpenIFFStream(Name,MODE_NEWFILE)))
  89.         Error = IoErr();
  90.     else
  91.     {
  92.         if(!(Error = PushChunk(Handle,ID_TERM,ID_CAT,IFFSIZE_UNKNOWN)))
  93.         {
  94.             if(!(Error = PushChunk(Handle,ID_TERM,ID_FORM,IFFSIZE_UNKNOWN)))
  95.             {
  96.                 if(!(Error = PushChunk(Handle,0,ID_VERS,IFFSIZE_UNKNOWN)))
  97.                 {
  98.                     struct TermInfo TermInfo;
  99.  
  100.                     TermInfo.Version    = CONFIG_FILE_VERSION;
  101.                     TermInfo.Revision    = CONFIG_FILE_REVISION;
  102.  
  103.                     if(WriteChunkBytes(Handle,&TermInfo,sizeof(struct TermInfo)) != sizeof(struct TermInfo))
  104.                         Error = IoErr();
  105.  
  106.                     if(!Error)
  107.                         Error = PopChunk(Handle);
  108.                 }
  109.  
  110.                 if(!Error)
  111.                 {
  112.                     if(!(Error = PushChunk(Handle,0,ID_TRST,sizeof(struct TrapSettings))))
  113.                     {
  114.                         struct TrapSettings TrapSettings;
  115.  
  116.                         memset(&TrapSettings,0,sizeof(TrapSettings));
  117.  
  118.                         TrapSettings.Enabled = WatchTraps;
  119.  
  120.                         if(WriteChunkBytes(Handle,&TrapSettings,sizeof(struct TrapSettings)) != sizeof(struct TrapSettings))
  121.                             Error = IoErr();
  122.  
  123.                         if(!Error)
  124.                             Error = PopChunk(Handle);
  125.                     }
  126.                 }
  127.  
  128.                 if(!Error)
  129.                     Error = PopChunk(Handle);
  130.             }
  131.  
  132.             if(!Error)
  133.             {
  134.                 struct TrapNode *Node;
  135.  
  136.                 for(Node = (struct TrapNode *)TrapList->lh_Head ; !Error && Node->Node.ln_Succ ; Node = (struct TrapNode *)Node->Node.ln_Succ)
  137.                 {
  138.                     if(!(Error = PushChunk(Handle,ID_TERM,ID_FORM,IFFSIZE_UNKNOWN)))
  139.                     {
  140.                         if(!(Error = PushChunk(Handle,0,ID_SEQN,strlen(Node->Node.ln_Name))))
  141.                         {
  142.                             if(WriteChunkBytes(Handle,Node->Node.ln_Name,strlen(Node->Node.ln_Name)) != strlen(Node->Node.ln_Name))
  143.                                 Error = IoErr();
  144.  
  145.                             if(!Error)
  146.                                 Error = PopChunk(Handle);
  147.                         }
  148.  
  149.                         if(!Error)
  150.                         {
  151.                             if(!(Error = PushChunk(Handle,0,ID_TRAP,strlen(Node->Command))))
  152.                             {
  153.                                 if(WriteChunkBytes(Handle,Node->Command,strlen(Node->Command)) != strlen(Node->Command))
  154.                                     Error = IoErr();
  155.  
  156.                                 if(!Error)
  157.                                     Error = PopChunk(Handle);
  158.                             }
  159.                         }
  160.  
  161.                         if(!Error)
  162.                             Error = PopChunk(Handle);
  163.                     }
  164.                 }
  165.             }
  166.  
  167.             if(!Error)
  168.                 Error = PopChunk(Handle);
  169.         }
  170.  
  171.         CloseIFFStream(Handle);
  172.     }
  173.  
  174.     if(Error)
  175.     {
  176.         DeleteFile(Name);
  177.         SetIoErr(Error);
  178.  
  179.         return(FALSE);
  180.     }
  181.     else
  182.     {
  183.         AddProtection(Name,FIBF_EXECUTE);
  184.  
  185.         return(TRUE);
  186.     }
  187. }
  188.  
  189.     /* LoadTraps(STRPTR Name):
  190.      *
  191.      *    Restore the trap list from a file.
  192.      */
  193.  
  194. BOOL
  195. LoadTraps(STRPTR Name,struct GenericList *TrapList)
  196. {
  197.     STATIC ULONG Stops[8] =
  198.     {
  199.         ID_TERM,ID_VERS,
  200.         ID_TERM,ID_SEQN,
  201.         ID_TERM,ID_TRAP,
  202.         ID_TERM,ID_TRST
  203.     };
  204.  
  205.     UBYTE SequenceBuffer[256],CommandBuffer[256];
  206.     struct TrapSettings    TrapSettings;
  207.     struct ContextNode *Chunk;
  208.     struct IFFHandle *Handle;
  209.     BOOL TrapSettingsFound;
  210.     LONG Error;
  211.  
  212.     TrapSettingsFound = FALSE;
  213.  
  214.     if(!(Handle = OpenIFFStream(Name,MODE_OLDFILE)))
  215.         Error = IoErr();
  216.     else
  217.     {
  218.         if(!(Error = StopChunks(Handle,(LONG *)Stops,4)))
  219.         {
  220.             SequenceBuffer[0] = CommandBuffer[0] = 0;
  221.  
  222.             while(!ParseIFF(Handle,IFFPARSE_SCAN))
  223.             {
  224.                 Chunk = CurrentChunk(Handle);
  225.  
  226.                 if(Chunk->cn_ID == ID_VERS)
  227.                 {
  228.                     struct TermInfo TermInfo;
  229.  
  230.                     if(ReadChunkBytes(Handle,&TermInfo,sizeof(struct TermInfo)) == sizeof(struct TermInfo))
  231.                     {
  232.                         if((TermInfo.Version > CONFIG_FILE_VERSION) || (TermInfo.Version == CONFIG_FILE_VERSION && TermInfo.Revision > CONFIG_FILE_REVISION) || (TermInfo.Version == 1 && TermInfo.Revision < 6))
  233.                         {
  234.                             Error = ERR_OUTDATED;
  235.  
  236.                             break;
  237.                         }
  238.                     }
  239.                     else
  240.                     {
  241.                         Error = IoErr();
  242.  
  243.                         break;
  244.                     }
  245.                 }
  246.  
  247.                 if(Chunk->cn_ID == ID_TRST)
  248.                 {
  249.                     if(ReadChunkBytes(Handle,&TrapSettings,sizeof(struct TrapSettings)) == sizeof(struct TrapSettings))
  250.                         TrapSettingsFound = TRUE;
  251.                     else
  252.                     {
  253.                         Error = IoErr();
  254.  
  255.                         break;
  256.                     }
  257.                 }
  258.  
  259.                 if(Chunk->cn_ID == ID_SEQN)
  260.                 {
  261.                     if(ReadChunkBytes(Handle,SequenceBuffer,Chunk->cn_Size) == Chunk->cn_Size)
  262.                         SequenceBuffer[Chunk->cn_Size] = 0;
  263.                     else
  264.                     {
  265.                         Error = IoErr();
  266.  
  267.                         break;
  268.                     }
  269.                 }
  270.  
  271.                 if(Chunk->cn_ID == ID_TRAP)
  272.                 {
  273.                     if(ReadChunkBytes(Handle,CommandBuffer,Chunk->cn_Size) == Chunk->cn_Size)
  274.                         CommandBuffer[Chunk->cn_Size] = 0;
  275.                     else
  276.                     {
  277.                         Error = IoErr();
  278.  
  279.                         break;
  280.                     }
  281.                 }
  282.  
  283.                 if(!Error && SequenceBuffer[0] && CommandBuffer[0])
  284.                 {
  285.                     struct TrapNode *Node;
  286.  
  287.                     if(Node = CreateTrapNode(SequenceBuffer,CommandBuffer))
  288.                     {
  289.                         AddGenericListNode(TrapList,(struct Node *)Node,ADD_GLIST_BOTTOM,FALSE);
  290.  
  291.                         SequenceBuffer[0] = CommandBuffer[0] = 0;
  292.                     }
  293.                     else
  294.                     {
  295.                         Error = ERROR_NO_FREE_STORE;
  296.  
  297.                         break;
  298.                     }
  299.                 }
  300.             }
  301.         }
  302.  
  303.         CloseIFFStream(Handle);
  304.     }
  305.  
  306.     if(Error)
  307.     {
  308.         SetIoErr(Error);
  309.  
  310.         return(FALSE);
  311.     }
  312.     else
  313.     {
  314.         TrapsChanged = FALSE;
  315.  
  316.         if(TrapSettingsFound)
  317.             WatchTraps = TrapSettings.Enabled;
  318.  
  319.         if(!TrapList->ListCount && WatchTraps)
  320.             WatchTraps = FALSE;
  321.  
  322.         return(TRUE);
  323.     }
  324. }
  325.  
  326.     /* TrapFilter(STRPTR Data,LONG Size):
  327.      *
  328.      *    Handle the trap list, similar to FlowFilter().
  329.      */
  330.  
  331. VOID
  332. TrapFilter(STRPTR Data,LONG Size)
  333. {
  334.     if(Size)
  335.     {
  336.         STATIC LONG WaitCount = 0;
  337.  
  338.         struct List    *List = (struct List *)&GenericListTable[GLIST_TRAP]->ListHeader;
  339.         struct TrapNode    *Node;
  340.  
  341.         LONG c,Mask;
  342.  
  343.         LockGenericList(GenericListTable[GLIST_TRAP]);
  344.  
  345.         if(Config->SerialConfig->StripBit8)
  346.             Mask = 0x7F;
  347.         else
  348.             Mask = 0xFF;
  349.  
  350.         do
  351.         {
  352.             BOOL MatchMade;
  353.  
  354.             c = (*Data++) & Mask;
  355.  
  356.             do
  357.             {
  358.                 MatchMade = FALSE;
  359.  
  360.                 for(Node = (struct TrapNode *)List->lh_Head ; Node->Node.ln_Succ ; Node = (struct TrapNode *)Node->Node.ln_Succ)
  361.                 {
  362.                     if(Node->Count == WaitCount)
  363.                     {
  364.                         if(c == (Node->Sequence[WaitCount] & Mask))
  365.                         {
  366.                             MatchMade = TRUE;
  367.  
  368.                             if(++Node->Count == Node->SequenceLen)
  369.                             {
  370.                                 struct DataMsg *Msg;
  371.  
  372.                                 Node->Count = 0;
  373.  
  374.                                 if(Msg = (struct DataMsg *)CreateMsgItem(sizeof(struct DataMsg) + strlen(Node->Command) + 1))
  375.                                 {
  376.                                     Msg->Type = DATAMSGTYPE_SERIALCOMMAND;
  377.                                     Msg->Data = (STRPTR)(Msg + 1);
  378.  
  379.                                     strcpy(Msg->Data,Node->Command);
  380.  
  381.                                     PutMsgItem(SpecialQueue,(struct MsgItem *)Msg);
  382.                                 }
  383.                             }
  384.                         }
  385.                     }
  386.                 }
  387.  
  388.                 if(MatchMade)
  389.                     WaitCount++;
  390.                 else
  391.                 {
  392.                     if(WaitCount)
  393.                     {
  394.                         WaitCount = 0;
  395.  
  396.                         for(Node = (struct TrapNode *)List->lh_Head ; Node->Node.ln_Succ ; Node = (struct TrapNode *)Node->Node.ln_Succ)
  397.                             Node->Count = 0;
  398.                     }
  399.                     else
  400.                         break;
  401.                 }
  402.             }
  403.             while(!WaitCount);
  404.         }
  405.         while(--Size);
  406.  
  407.         UnlockGenericList(GenericListTable[GLIST_TRAP]);
  408.     }
  409. }
  410.